/*-------------------------------------------------------------------------
 *
 * pg_shmem.h
 *	  跨平台的共享内存支持 API。
 *
 * 每个端口预计支持具有大约 SysV 风格的共享内存；特别是，一个内存块不是匿名的，而是具有一个 ID，并且我们必须能够判断是否有任何剩余进程附加到指定 ID 的块上。
 *
 * 为了简化 SysV 实现，ID 假定由两个无符号长值组成（在 SysV 术语中，这些是键和 ID）。其他平台如果只需要一个 ID 号码可以忽略第二个值。
 *
 *
 * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * src/include/storage/pg_shmem.h
 *
 *-------------------------------------------------------------------------
 */
#ifndef PG_SHMEM_H
#define PG_SHMEM_H

#include "storage/dsm_impl.h"

typedef struct PGShmemHeader	/* 所有 Postgres shmem 的标准头 */
{
	int32		magic;			/* 用于识别 Postgres 段的魔法编号 */
#define PGShmemMagic  679834894
	pid_t		creatorPID;		/* 创建进程的 PID（已设定但不可读） */
	Size		totalsize;		/* 段的总大小 */
	Size		freeoffset;		/* 第一个空闲空间的偏移量 */
	dsm_handle	dsm_control;	/* 动态共享内存控制段的 ID */
	void	   *index;			/* ShmemIndex 表的指针 */
#ifndef WIN32					/* Windows 不提供有用的 inode# */
	dev_t		device;			/* 设备数据目录所在 */
	ino_t		inode;			/* 数据目录的 inode 号 */
#endif
} PGShmemHeader;

/* GUC 变量 */
extern PGDLLIMPORT int shared_memory_type;
extern PGDLLIMPORT int huge_pages;
extern PGDLLIMPORT int huge_page_size;

/* 巨型页面的可能值 */
typedef enum
{
	HUGE_PAGES_OFF,
	HUGE_PAGES_ON,
	HUGE_PAGES_TRY
}			HugePagesType;

/* 共享内存类型的可能值 */
typedef enum
{
	SHMEM_TYPE_WINDOWS,
	SHMEM_TYPE_SYSV,
	SHMEM_TYPE_MMAP
}			PGShmemType;

#ifndef WIN32
extern PGDLLIMPORT unsigned long UsedShmemSegID;
#else
extern PGDLLIMPORT HANDLE UsedShmemSegID;
extern PGDLLIMPORT void *ShmemProtectiveRegion;
#endif
extern PGDLLIMPORT void *UsedShmemSegAddr;

#if !defined(WIN32) && !defined(EXEC_BACKEND)
#define DEFAULT_SHARED_MEMORY_TYPE SHMEM_TYPE_MMAP
#elif !defined(WIN32)
#define DEFAULT_SHARED_MEMORY_TYPE SHMEM_TYPE_SYSV
#else
#define DEFAULT_SHARED_MEMORY_TYPE SHMEM_TYPE_WINDOWS
#endif

#ifdef EXEC_BACKEND
extern void PGSharedMemoryReAttach(void);
extern void PGSharedMemoryNoReAttach(void);
#endif

extern PGShmemHeader *PGSharedMemoryCreate(Size size,
										   PGShmemHeader **shim);
extern bool PGSharedMemoryIsInUse(unsigned long id1, unsigned long id2);
extern void PGSharedMemoryDetach(void);
extern void GetHugePageSize(Size *hugepagesize, int *mmap_flags);

#endif							/* PG_SHMEM_H */
